﻿using System.Security.Cryptography;
using System.Text;

namespace GitHubCopilotProxies.Handlers;

public class User
{
    public static async Task GetLoginUser(HttpContext httpContext)
    {
        var strToken = httpContext.Request.Headers.Authorization.ToString().Split(' ').Last();
        if (strToken is not { Length: > 0 })
        {
            httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
            return;
        }
        string infoJson = $$"""{"avatar_url": "https://avatars.githubusercontent.com/u/9919?v=4","bio": null,"blog": "","company": null,"created_at": "2008-05-11T04:37:31Z","email": null,"events_url": "https://api.github.com/users/github/events{/privacy}","followers": 42848,"followers_url": "https://api.github.com/users/github/followers","following": 0,"following_url": "https://api.github.com/users/github/following{/other_user}","gists_url": "https://api.github.com/users/github/gists{/gist_id}","gravatar_id": "","hireable": null,"html_url": "https://github.com/github","id": 9919,"location": "San Francisco, CA","login": "github","name": "GitHub","node_id": "DEyOk9yZ2FuaXphdGlvbjk5MTk=","organizations_url": "https://api.github.com/users/github/orgs","public_gists": 0,"public_repos": 498,"received_events_url": "https://api.github.com/users/github/received_events","repos_url": "https://api.github.com/users/github/repos","site_admin": false,"starred_url": "https://api.github.com/users/github/starred{/owner}{/repo}","subscriptions_url": "https://api.github.com/users/github/subscriptions","twitter_username": null,"type": "User","updated_at": "2022-11-29T19:44:55Z","url": "https://api.github.com/users/github"}""";
        httpContext.ResponseWithXOAuthScopes();
        await httpContext.ResponseJsonAsync(infoJson);
    }
    public static async Task GetUserOrgs(HttpContext httpContext)
    {
        httpContext.ResponseWithXOAuthScopes();
        await httpContext.ResponseJsonAsync("[]");
    }
    public static async Task GetMembership(HttpContext httpContext, string teamID, string username)
    {
        string infoJson = $$"""
        {
            "message":          "NotFound",
            "documentation_url":"https://docs.github.com/rest/teams/members#get-team-membership-for-a-user-legacy",
            "status":           "404",
            "teamID":           "{{teamID}}",
            "username":         "{{username}}"
        }
        """;
        httpContext.ResponseWithXOAuthScopes();
        await httpContext.ResponseJsonAsync(infoJson);
    }

    private static readonly Random _random = new Random();
    public static async Task GetCopilotInternalUser(HttpContext httpContext)
    {
        httpContext.Response.ContentType = "application/json; charset=utf-8";
        static string GenerateTrackingID()
        {
            var randomStr = $"{DateTime.UtcNow.Ticks}{_random.Next()}";
            using var md5 = MD5.Create();
            var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(randomStr));
            return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
        }
        static string GenerateAssignedDate()
        {
            var now = DateTime.UtcNow;
            var daysAgo = _random.Next(30);
            var randomTime = now.AddDays(-daysAgo)
                .AddHours(_random.Next(24))
                .AddMinutes(_random.Next(60));
            return randomTime.ToString("o"); // ISO 8601 格式
        }
        string infoJson = $$"""
        {
            "access_type_sku":          "free_educational",
            "analytics_tracking_id":    "{{GenerateTrackingID()}}",
            "assigned_date":            "{{GenerateAssignedDate()}}",
            "can_signup_for_limited":   false,
            "chat_enabled":             true,
            "organization_login_list":  [],
            "organization_list":        []
        }
        """;
        await httpContext.ResponseJsonAsync(infoJson);
    }
    public static async Task GetDisguiseCopilotInternalV2Token(HttpContext httpContext)
    {
        var strToken = httpContext.Request.Headers.Authorization.ToString().Split(' ').Last();
        if (strToken is not { Length: > 0 })
        {
            httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
            return;
        }

        var trackingId = Guid.NewGuid();
        var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        var expiresAt = now + 1800;
        var sku = "copilot_for_business_seat";

        static string JsonMap2Token(Dictionary<string, object> data)
        {
            if (data.Count == 0) return string.Empty;
            var keys = data.Keys.ToList();
            keys.Sort();
            var sb = new StringBuilder();
            for (int i = 0; i < keys.Count; i++)
            {
                if (i > 0) sb.Append(";");
                sb.Append(keys[i]);
                sb.Append("=");
                sb.Append(data[keys[i]]);
            }
            return sb.ToString();
        }
        static string Sha256Sign(string data)
        {
            using (var sha256 = SHA256.Create())
            {
                var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(data));
                return BitConverter.ToString(hash).Replace("-", "").ToLower();
            }
        }
        static string Token2Sign(string token)
        {
            const string salt = "TiXrNaj4avvMuD4w";
            var sign = Sha256Sign($"{token};salt={salt}");
            return sign;
        }
        static string JsonMap2SignToken(Dictionary<string, object> data)
        {
            var token = JsonMap2Token(data);
            if (string.IsNullOrEmpty(token))
                return string.Empty;
            var sign = Token2Sign(token);
            return $"{token};8kp=1:{sign}";
        }
        var copilotToken = JsonMap2SignToken(new Dictionary<string, object>()
        {
            {"tid", trackingId },
            {"exp", expiresAt },
            {"sku",  sku },
            {"st", "dotcom" },
            {"chat", 1 },
            {"u", "github" },
        });

        string jsonInfo = $$"""
        {
            "annotations_enabled":true,
            "chat_enabled":true,
            "chat_jetbrains_enabled":true,
            "code_quote_enabled":true,
            "code_review_enabled":false,
            "codesearch":true,
            "copilot_ide_agent_chat_gpt4_small_prompt":false,
            "copilotignore_enabled":false,
            "endpoints":{
                "api":"https://api.copilot.supercopilot.top",
                "origin-tracker":"https://origin-tracker.individual.githubcopilot.com",
                "proxy":"https://copilot-proxy.copilot.supercopilot.top",
                "telemetry":"https://copilot-telemetry-service.copilot.supercopilot.top"
            },
            "expires_at":{{expiresAt}},
            "individual":true,
            "intellij_editor_fetcher":false,
            "limited_user_quotas":null,
            "limited_user_reset_date":null,
            "nes_enabled":false,
            "prompt_8k":true,
            "public_suggestions":"disabled",
            "refresh_in":1500,
            "sku":"{{sku}}",
            "snippy_load_test_enabled":false,
            "telemetry":"disabled",
            "token":"{{copilotToken}}",
            "tracking_id":"{{trackingId}}",
            "vs_editor_fetcher":false,
            "vsc_electron_fetcher":false,
            "vsc_electron_fetcher_v2":false,
            "vsc_panel_v2":false,
            "xcode":true,
            "xcode_chat":true
        }
        """;
        await httpContext.ResponseJsonAsync(jsonInfo);
    }

}
